<?php

namespace app\admin\model\inventory;

use think\Model;
use think\Log;
//use traits\model\SoftDelete;
use think\Db;
use app\common\model\Inventory;
use think\Exception;
use app\api\controller\Wms;
use app\admin\model\Kisapi;
use app\admin\model\information\KisBaseinfo;

class Procure extends Model
{
    //use SoftDelete;
    // 表名
    protected $name = 'procure';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'datetime';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [

    ];
    
    protected $type = [
        'quantity' => 'quantity',
        'store_quantity' => 'quantity',
        'warehousing_quantity' => 'quantity',
        'no_quantity' => 'quantity',
        'unit_price' => 'quantity',
        'total_price' => 'quantity',
    ];
    
    public static function getOrderTypeList()
    {
        return ['采购订单', 'MES产品入库', '生产任务单'];
    }

     /**
     * 新增前自动生成编码
     */
    protected static function init()
    {
        Procure::event('before_delete', function ($procure) {
            //mes单才这么处理
            if($procure->data['type'] == 1){
                if(!$procure->data['status']){
                    exception('该单号已被下游单据引用');
                }

                $kcData = [
                    'code'=>$procure->data['warehousing_code'],
                    'code_date'=>$procure->data['order_date'],
                    'inv_number'=>$procure->data['inventory_number'],
                    'cBatch' => $procure->data['cBatch'],
                    'quantity'=> $procure->data['quantity'],
                    'warehouse_id'=>7676,
                    'shelves_id'=>1
                ];

                //更新本地库存 20240423质检不形成库存了。所以没库存
                //Wmskc::OperateWmsKc($kcData, 'dec', 14,'删除MES产品记录删库存');
            }
        });
    }

    /**
     * 修改采购订单数量，满足条件的关闭
     * @param $source_code
     * @param $row_id
     * @param $fqty
     * @return void
     */
    public static function updateProduceQty($source_code,$row_id,$fqty){
        $where = [
            'warehousing_code' => $source_code,
            'row_id' => $row_id
        ];
        
        $produce = self::where($where)->find();
        
        if(!$produce){
            Log::error("找不到对应采购单记录:单号{$source_code},行号{$row_id}");
            exception('找不到Wsm平台对应入库分析记录');
        }
        
        if($produce->no_quantity<=0){
            exception('采购单记录待入库记录为0');
        }
        
        if($produce->no_quantity<=$fqty){
            //关闭采购单
            $produce->status = 0;
            $produce->deletetime = date('Y-m-d H:i:s',time());
        }else{
            $produce->status = 1;
            $produce->deletetime = null;
        }
        $produce->save();
        
        $produce->setInc('warehousing_quantity',$fqty);
        $produce->setDec('no_quantity',$fqty);
    }
    
    public static function getSql()
    {
        //没启用u8，默认都是入库0
        $warehousing_quantity_sql = '0 warehousing_quantity';
        if(config('site.backu8')){
            //d.dVeriDate is not null and //有无审核都算入库
            $warehousing_quantity_sql = 'ISNULL((select sum(r.iQuantity) from rdrecords01 as r inner join rdrecord01 as d on r.ID=d.ID where  r.iPOsID=i.ID),0) as warehousing_quantity';
        }
        
        //获取u8采购订单
        $sql = Db::connect('database.sec')->table('PO_Podetails')->alias('i')
        ->join('PO_Pomain u','i.POID=u.POID')
        ->join('Vendor c','u.cVenCode =c.cVenCode ')
        ->field('i.ID,i.iQuantity,i.cbCloseDate,u.cPOID,i.dArriveDate,i. ivouchrowno,
i.cInvCode,u.cAuditTime,u.dPODate,c.cVenCode,i.iUnitPrice,i.iMoney,
c.cVenName,i.irowno,i.cbMemo,u.cMemo,'.$warehousing_quantity_sql)
            ->where([
                'i.cbCloseDate'=>null,//行关闭日期
                'u.cState' => 1, //1有效 0待审 2关闭
                'i.cInvCode' => ['not like','0810%']
            ])
            ->where("i.iReceivedQTY is null or i.iReceivedQTY < i.iQuantity");
            
            /*
             * SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER ( ORDER BY rand()) AS ROW_NUMBER FROM 
             (SELECT  i.ID,i.iQuantity,i.cbCloseDate,u.cPOID,i.dArriveDate,i. ivouchrowno,
i.cInvCode,u.cAuditTime,u.dPODate,c.cVenCode,i.iUnitPrice,i.iMoney,
c.cVenName,i.irowno,i.cbMemo,u.cMemo,ISNULL((select sum(r.iQuantity) from rdrecords01 as r 
inner join rdrecord01 as d on r.ID=d.ID where  r.iPOsID=i.ID),0) as warehousing_quantity FROM [PO_Podetails] [i] 
INNER JOIN [PO_Pomain] [u] ON [i].[POID]=[u].[POID] INNER JOIN [Vendor] [c] ON [u].[cVenCode]=[c].[cVenCode] WHERE  
[i].[cbCloseDate] IS NULL  AND [u].[cState] = 1  AND [i].[cInvCode] NOT LIKE '0810%'  AND 
(  i.iReceivedQTY is null or i.iReceivedQTY < i.iQuantity ) and u.cPOID='po2023100047' ) AS thinkphp) AS T1
             *   */
            //->order('dPODate','desc');
            //采购订单子表标识  r.iPOsID  d.dVeriDate审核日期
            return $sql;
    }
    
    /*
     * 获取采购订单日期，期间，读配置 kis_procure_date_type
     *   */
    public static function getProcureCfgDate(){
        $startDate = date('Y-m-d',time());
        $endDate = date('Y-m-d',time());
        
        if(config('site.kis_procure_date_type')){
            switch (config('site.kis_procure_date_type')){
                case 1:
                    $startDate = date("Y-m-d",strtotime("-1 month")); 
                    break;
                case 2:
                    $startDate = date("Y-m-d",strtotime("-2 month")); 
                    break;
                case 3:
                    $startDate = date("Y-m-d",strtotime("-3 month")); 
                    break;
                case 4:
                    $startDate = date("Y-m-d",strtotime("-6 month")); 
                    break;
                case 5:
                    $startDate = date("Y-m-d",strtotime("-12 month")); 
                    break;
            }
        }
        
        return [
            'StartTime' => $startDate,
            'EndTime' => $endDate
        ];
    }

    /*
     * 获取生产任务日期，期间，读配置 kis_pro_yf_task_date_type  研发中心
     *   */
    public static function getProyftaskCfgDate(){
        $startDate = date('Y-m-d',time());
        $endDate = date('Y-m-d',time());
        
        if(config('site.kis_pro_yf_task_date_type')){
            switch (config('site.kis_pro_yf_task_date_type')){
                case 1:
                    $startDate = date("Y-m-d",strtotime("-1 month")); 
                    break;
                case 2:
                    $startDate = date("Y-m-d",strtotime("-2 month")); 
                    break;
                case 3:
                    $startDate = date("Y-m-d",strtotime("-3 month")); 
                    break;
                case 4:
                    $startDate = date("Y-m-d",strtotime("-6 month")); 
                    break;
                case 5:
                    $startDate = date("Y-m-d",strtotime("-12 month")); 
                    break;
            }
        }
        
        return [
            'StartTime' => $startDate,
            'EndTime' => $endDate
        ];
    }
    
    /**
     * 同步数据
     * 默认源头：procureList采购订单，getIcmoList生产任务
     * type 0采购订单，1mes产品入库，2生产任务   (0,2金蝶取数)
     */
    public function getProcureData($type = 0)
    {
        $condition = [
            'PageSize'=>1,
            'PageIndex'=>1
        ];

        if($type==0){
            $date_arr = self::getProcureCfgDate();
            $condition = array_merge($condition,$date_arr);
            $row = Kisapi::getDataByName('procureList',$condition,true);
            $count = 0;
            if(isset($row['data_totle'])){
                $count = $row['data_totle'];
            }
        }else if($type==2){
            $date_arr = self::getProyftaskCfgDate();
            //$condition = array_merge($condition,$date_arr);
            $condition['fdept'] = 247;//研发中心
            $row = Kisapi::getDataByName('getIcmoList',$condition,true);
            $count = 0;
            if(isset($row['data_totle'])){
                $count = $row['data_totle'];
            }
        }
        
        if(!$count){
            //exception("已经最新数据，没有数据可以同步");
            return false;
        }
        
        //Db::startTrans();
        //先清后增
        //Db::name('procure')->execute('TRUNCATE TABLE fa_procure');
        $newList =[];
        if($count>1000) {
            for($i=1;$i<=(intval($count/1000)+1);$i++){
                 $condition['PageSize'] = 1000;
                 $condition['PageIndex'] = $i;
                 if($type==0){
                    $data = Kisapi::getDataByName('procureList',$condition,true);
                 }else if($type==2){
                    $data = Kisapi::getDataByName('getIcmoList',$condition,true);
                 }
                 //$newList = array_merge($newList,$data);
                 $kis_mater_keys = $this->analysisKisData($data,$type);
                 $newList = array_merge($newList,$kis_mater_keys);
            }
        }else{
            $condition['PageSize'] = 1000;
            if($type==0){
                $newList = Kisapi::getDataByName('procureList',$condition,true);
             }else if($type==2){
                $newList = Kisapi::getDataByName('getIcmoList',$condition,true);
             }
			 $kis_mater_keys = $this->analysisKisData($newList,$type);
             $newList = array_merge($newList,$kis_mater_keys);
        }
        
        if(empty($newList)||!isset($newList['data_item'])){
            //exception("已经最新数据，没有数据可以同步");
            return false;
        }
        
        $supplier_arr = KisBaseinfo::getSupplier(false,false,[],true);
        $digits = getDigits();//小数点位数
        $temp_arr = [];
        
        if($newList){
            if(!count($newList['data_item'])) return ;//没数据，直接false
            foreach ($newList['data_item'] as $k=>$head) {
                if($type==0){//采购订单
                    $body = $head['t_BillPurOrderEntry'];
                    unset($head['t_BillPurOrderEntry']);
                    
                    if(!$body){
                        continue;
                    }
                    
                    $FSupplyName = '';//供应商名称
                    if($head['fSupplyId']&&isset($supplier_arr[$head['fSupplyId']])){
                        $FSupplyName = $supplier_arr[$head['fSupplyId']];
                    }
                    
                    foreach ($body as $value){
                        if($value['fQty']-$value['fStockQty']<=0){
                            continue;
                        }
                        
                        $inventory = Inventory::get($value['fItemId']);
                        $data = [
                            'auto_id' => $value['fDetailID'],
                            'FInterID' => $head['fInterId'],
                            'warehousing_code' => $head['fBillNo'],
                            'order_date' => substr($head['fDate'],0, 10),
                            'warehousing_date' => substr($head['fArriveDate'],0,10),
                            'factory_code' => $head['fSupplyId'],
                            'factory_name' => $FSupplyName,
                            'F_104' => isset($head['F_104'])?$head['F_104']:'',
                            'row_id' => $value['fEntryId'],
                            'fItemId' => $value['fItemId'],
                            'inventory_number' => $inventory->number,
                            'quantity' => $value['fQty'],
                            'warehousing_quantity' => $value['fStockQty'],
                            'no_quantity' => $value['fQty']-$value['fStockQty'],
                            'sh_time'=> substr($head['fCheckDate'],0,10),
                            'remark' => isset($head['fExplanation'])?$head['fExplanation']:'',
                            'b_remark' => isset($value['fNote'])?$value['fNote']:'',
                            'unit_price' => $value['fPrice'],
                            'total_price' => $value['fAmount'],
                            'createtime'=>date('Y-m-d H:i:s',time()),
                            'type' => $type
                        ];
                        
                        $id = db('procure')->where([
                            'auto_id' => $value['fDetailID'],
                            'type' => $type
                        ])->value('id');
                        if($id){
                            $data['id'] = $id;
                        }
    
                        $temp_sum_qty = db('temporary')->where([
                            'auto_id'=>$value['fDetailID'],
                            'order_list'=>1,
                            //'status'=>0//待执行数量
                            'status'=>['IN',[0,1]]//待执行数&已执行数
                        ])->sum('quantity',0);
                        
                        if($temp_sum_qty>0){
                            $data['warehousing_quantity'] = round($temp_sum_qty,$digits);//$value['warehousing_quantity']+
                            $data['no_quantity'] = $value['fQty']-$data['warehousing_quantity'];
                            if ($data['no_quantity']<=0){
                                $data['status'] = 0;//关闭
                                $data['close_time'] = date('Y-m-d', time());
                            }
                        }
                        
                        //获得推荐路径，在物料里
                        $wh_sh_arr = Inventory::getTjWhShByInvNumber($value['fItemId']);
                        if($wh_sh_arr){
                            $data = array_merge($data,$wh_sh_arr);
                        }else{
                            //不存在该物料，则跳过
                            continue;
                        }
                        $temp_arr[] = $data;
                    }
                }else if($type==2){
                    //$inventory = Inventory::get($head['FItemID']);
                    if($head['FQty']-$head['FCommitQty']<=0){
                        continue;
                    }

                    //结案 跳过
                    if($head['FStatus']==3){
                        continue;
                    }

                    $data = [
                        'auto_id' => $head['FInterID'],
                        'FInterID' => $head['FInterID'],
                        'warehousing_code' => $head['FBillNo'],
                        'order_date' => substr($head['FCheckDate'],0, 10),
                        'warehousing_date' => substr($head['FPlanCommitDate'],0,10),
                        'factory_code' => $head['FWorkShop'],
                        'factory_name' => $head['FWorkShopName'],
                        'row_id' => 0,
                        'fItemId' => $head['FItemID'],
                        'inventory_number' => $head['FNumber'],
                        'quantity' => $head['FQty'],
                        'warehousing_quantity' => $head['FCommitQty'],
                        'no_quantity' => $head['FQty']-$head['FCommitQty'],
                        'sh_time'=> substr($head['FCheckDate'],0,10),
                        'remark' => isset($head['FNote'])?$head['FNote']:'',
                        'b_remark' => '',
                        'unit_price' => 0,
                        'total_price' => 0,
                        'createtime'=>date('Y-m-d H:i:s',time()),
                        'type' => $type
                    ];

                    $id = db('procure')->where([
                        'warehousing_code' => $head['FBillNo'],
                        'auto_id' => $head['FInterID'],
                        'type' => $type
                    ])->value('id');

                    if($id){
                        $data['id'] = $id;
                    }
    
                    $temp_sum_qty = db('temporary')->where([
                        'source_code' => $head['FBillNo'],
                        'auto_id'=>$head['FInterID'],
                        'order_list'=>1,
                        //'status'=>0//待执行数量
                        'status'=>['IN',[0,1]]//待执行数&已执行数
                    ])->sum('quantity',0);
                        
                    if($temp_sum_qty>0){
                        $data['warehousing_quantity'] = round($temp_sum_qty,$digits);//$value['warehousing_quantity']+
                        $data['no_quantity'] = $head['FQty']-$data['warehousing_quantity'];
                        if ($data['no_quantity']<=0){
                            $data['status'] = 0;//关闭
                            $data['close_time'] = date('Y-m-d', time());
                        }
                    }
                        
                    //获得推荐路径，在物料里
                    $wh_sh_arr = Inventory::getTjWhShByInvNumber($head['FItemID']);
                    if($wh_sh_arr){
                        $data = array_merge($data,$wh_sh_arr);
                    }else{
                        //不存在该物料，则跳过
                        continue;
                    }
                    $temp_arr[] = $data;
                }
            }
        }
        
        if($temp_arr){
            self::saveAll($temp_arr);
        }
        
        return true;
        //更新库存json文件
        //$apiWms = new Wms();
        //$apiWms->getProcureList('add','./uploads/data/');
    }

    // 更新数据
    public function updateProducedata($source_code,$auto_id,$pdaorder = ''){
        if(!$source_code||!$auto_id){
            return ;
        }

        $procure = self::where([
            'auto_id' => $auto_id,
            'warehousing_code' => $source_code
        ])
        ->find();

        if(!$procure){
            exception('找不到源单'.$source_code);
        }

        $temp_sum_qty = db('temporary')->where([
            'source_code' => $source_code,
            'auto_id'=>$auto_id,
            'status'=>0//待执行数量
        ])->sum('quantity',0);
                    
        $digits = 4;
        $qty_format_arr = config('site.float_data_formatter');
        if(isset($qty_format_arr['digits'])){
            $digits = $qty_format_arr['digits'];
        }

        if($pdaorder){
            //删除pda单据，改原单数
             
            //已入库数,减掉
            $procure->setDec('warehousing_quantity',$pdaorder->quantity);
            //待入库数,增加
            $procure->setInc('no_quantity',$pdaorder->quantity);
        }else{
            //已入库数
            $procure->warehousing_quantity = round($procure->warehousing_quantity+$temp_sum_qty,$digits);
            //待入库数
            $procure->no_quantity = $procure->quantity - $procure->warehousing_quantity;
        }
        
        if ($procure->no_quantity<=0){
            $procure->status = 0;//关闭
            $procure->close_time = date('Y-m-d', time());
            $procure->save();
        }else{
            $procure->status = 1;//开启
            $procure->close_time = null;
            $procure->save();
        }
    }

    public function analysisKisData($data,$type){
        if(!count($data['data_item'])) return [];//没数据，直接返回
        $keys = [];
        foreach ($data['data_item'] as $k=>$head) {
            if ($type == 0) {//采购订单
                $body = $head['t_BillPurOrderEntry'];
                unset($head['t_BillPurOrderEntry']);

                if (!$body) {
                    continue;
                }
                foreach ($body as $value) {
                    if ($value['fQty'] - $value['fStockQty'] <= 0) {
                        continue;
                    }
                    $warehousing_code = $head['fBillNo'];
                    $auto_id = $value['fDetailID'];
                    $keys[] = "{$warehousing_code}-{$auto_id}";
                }
            }else if($type==2) {
                //$inventory = Inventory::get($head['FItemID']);
                if ($head['FQty'] - $head['FCommitQty'] <= 0) {
                    continue;
                }
                $warehousing_code = $head['FBillNo'];
                $auto_id = $head['FInterID'];
                $keys[] = "{$warehousing_code}-{$auto_id}";
            }else if($type==3) {//委外订单
                $body = $head['t_BillPurOrderEntry'];
                unset($head['t_BillPurOrderEntry']);
                foreach ($body as $value) {
                    if ($value['fQty'] - $value['fStockQty'] <= 0) {
                        continue;
                    }
                    $auto_id = $value['fDetailID'];
                    $warehousing_code = $head['fBillNo'];
                    $keys[] = "{$warehousing_code}-{$auto_id}";
                }
            }
        }

        return $keys;
    }

    public function SyncDel(){
        $api_names = [
            0=>'procureList',
            2=>'getIcmoList'
        ];
        $condition = [
            'PageSize'=>1,
            'PageIndex'=>1
        ];
        $date_arrs = [
            0 => self::getProcureCfgDate(),
            2 => self::getProyftaskCfgDate(),
        ];
        $kisList = [];
        $localList = [];
        $model = new Procure();
        foreach($api_names as $type => $api_name){
            $date_arr = $date_arrs[$type];
            $params = array_merge($condition,$date_arr);

            if($type == 2){
                $procure_list = $model
                    ->where('type',2)
                    ->column('id','concat(warehousing_code,"-",auto_id)');
            }else{
                
                $procure_list = $model
                    ->where('type',$type)
                    ->whereBetween('order_date',[$date_arr['StartTime'],$date_arr['EndTime']])
                    ->column('id','concat(warehousing_code,"-",auto_id)');
            }
            $localList = array_merge($localList,$procure_list);

            $row = Kisapi::getDataByName($api_name,$params,true);
            $count = 0;
            if(isset($row['data_totle'])){
                $count = $row['data_totle'];
            }
            if($count>1000) {
                for($i=1;$i<=(intval($count/1000)+1);$i++){
                    $params['PageSize'] = 1000;
                    $params['PageIndex'] = $i;
                    $data = Kisapi::getDataByName($api_name,$params,true);
                    $kis_mater_keys = $this->analysisKisData($data,$type);
                    $kisList = array_merge($kisList,$kis_mater_keys);
                }
            }else{
                $params['PageSize'] = 1000;
                $data = Kisapi::getDataByName($api_name,$params,true);
                $kis_mater_keys = $this->analysisKisData($data,$type);
                $kisList = array_merge($kisList,$kis_mater_keys);
            }
        }
        
        if(!count($kisList)){//已经是最新了
            return;
        }
        $model = new Procure();

        foreach($kisList as $kisKey){
            if(isset($localList[$kisKey])){
                unset($localList[$kisKey]);
            }
        }
        $del_ids = array_values($localList);
        $model->whereIn('id',$del_ids)->delete();
        return;
    }
}
